import React, { useRef, useEffect } from 'react';
import CodeMirror from '@uiw/react-codemirror';
import { json } from '@codemirror/lang-json';
import { search } from "@codemirror/search";
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { EditorView } from "@codemirror/view";
import { EditorSelection } from '@codemirror/state';
import { useDispatch, useSelector } from 'react-redux';
import { State } from '@/apps/panel/reducers';
import { updateUI, saveSourceCodeToEditing, setSourceCurrent, setEditorActiveTab } from '@/apps/panel/actions'
import { eventBus } from '@/common/eventBus';
import './index.less'

interface SourceViewProps {
    readOnly?: boolean;
}

interface SourceViewStyles {
    container: React.CSSProperties;
}

const styles: SourceViewStyles = {
    container: {
        height: '100%',
        width: '100%',
        border: '1px solid #d9d9d9',
        borderRadius: '4px',
        overflow: 'hidden',
        backgroundColor: '#282c34',
        boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)'
    }
};
let isScrolling = false;
export default function SourceView({ readOnly = false }: SourceViewProps) {

    const editorViewRef = useRef<EditorView | null>(null);
    const dispatch = useDispatch()
    const sourceText = useSelector((state: State) => state.editor.editingSource.pure || '')
    const sourceTextModified = useSelector((state: State) => state.editor.editingSource.current || '')
    const commands = useSelector((state: State) => state.editor.editing.commands)
    // 焦点/失焦扩展
    const focusExtension = EditorView.domEventHandlers({
        focus: () => {
            dispatch(updateUI({
                focusArea: 'code_source'
            }))
        },
        blur: () => {
            // 根据源码视图更新列表视图
            dispatch(saveSourceCodeToEditing(sourceTextModified) as any)
        },
    });

    // 光标移动扩展
    const cursorExtension = EditorView.updateListener.of(update => {
        if (update.selectionSet) {
            const pos = update.state.selection.main.head;
            console.log("Cursor position:", pos);
        }
    });

    const handleCreateEditor = (view: EditorView) => {
        editorViewRef.current = view;
    };

    const selectAndScroll = (from: number, to: number) => {
        if (!editorViewRef.current) return;
        const { view } = editorViewRef.current;

        view.dispatch({
            selection: EditorSelection.range(from, to),
            effects: EditorView.scrollIntoView(from, {
                y: 'center',
                x: 'center',
            }),
        });
    };

    useEffect(() => {
        // 跳转到源码
        const jumpToSourceCode = (commandIndex: number) => {
            dispatch(setEditorActiveTab('source_view'))
            if (isScrolling) return;
            isScrolling = true;
            requestAnimationFrame(() => {
                const headingLineCount = 4;
                const lineCountForCommand = (command: any) => {
                    return 6 + (command.targetOptions ? (command.targetOptions.length + 2) : 0)
                }
                let startLine = headingLineCount;
                for (let i = 0; i < commandIndex; i++) {
                    startLine += lineCountForCommand(commands[i])
                }
                const endLine = startLine + lineCountForCommand(commands[commandIndex])
                selectAndScroll(startLine, endLine)
                isScrolling = false;
            });
        }
        eventBus.on('jumpToSourceCode', jumpToSourceCode); // 👂 监听事件
        return () => {
            eventBus.off('jumpToSourceCode', jumpToSourceCode); // 卸载时取消监听
        }
    }, []);

    return (
        <div className='source-view' style={styles.container}>
            <CodeMirror
                value={sourceText}
                height="100%"
                width='100%'
                theme={oneDark}
                extensions={[javascript({
                    jsx: true,
                    typescript: true
                }),
                    focusExtension,
                    cursorExtension,
                ]}
                readOnly={readOnly}
                basicSetup={{
                    lineNumbers: true,
                    highlightActiveLineGutter: true,
                    highlightSpecialChars: true,
                    foldGutter: true,
                    drawSelection: true,
                    dropCursor: true,
                    allowMultipleSelections: true,
                    indentOnInput: true,
                    syntaxHighlighting: true,
                    bracketMatching: true,
                    closeBrackets: true,
                    autocompletion: true,
                    rectangularSelection: true,
                    crosshairCursor: true,
                    highlightActiveLine: true,
                    highlightSelectionMatches: true,
                    closeBracketsKeymap: true,
                    searchKeymap: true,
                    foldKeymap: true,
                    completionKeymap: true,
                    lintKeymap: true,
                }}
                onChange={(value, viewUpdate) => {
                    dispatch(setSourceCurrent(value))
                    console.log(value, viewUpdate)
                }}
                onCreateEditor={handleCreateEditor}
            />
        </div>
    );
};